package com.rabbiter.oes.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rabbiter.oes.dto.JudgeDTO;
import com.rabbiter.oes.dto.MultiDTO;
import com.rabbiter.oes.dto.ScoreDTO;
import com.rabbiter.oes.dto.fillDTO;
import com.rabbiter.oes.entity.*;
import com.rabbiter.oes.enums.QuestionEnum;
import com.rabbiter.oes.mapper.*;
import com.rabbiter.oes.service.ScoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ScoreServiceImpl extends ServiceImpl<ScoreMapper, Score> implements ScoreService {

    // 试卷信息
    @Autowired
    private ExamManageMapper examManageMapper;
    // 试卷与考题对应关系表
    @Autowired
    private PaperMapper paperMapper;

    // 选择题
    @Autowired
    private MultiQuestionMapper multiQuestionMapper;
    // 判断题
    @Autowired
    private JudgeQuestionMapper judgeQuestionMapper;
    // 填空题
    @Autowired
    private FillQuestionMapper fillQuestionMapper;

    // 选择题答题记录
    @Autowired
    private MultiQuestionHistoryMapper multiQuestionHistoryMapper;

    // 判断题答题记录
    @Autowired
    private JudgeQuestionHistoryMapper judgeQuestionHistoryMapper;

    // 填空题答题记录
    @Autowired
    private FillQuestionHistoryMapper fillQuestionHistoryMapper;

    @Override
    @Transactional
    public int add(ScoreDTO dto) {
        // 学生id
        Integer studentId = dto.getStudentId();
        // 填写的选择题
        List<MultiDTO> multis = dto.getMultis();
        // 填写的填空题
        List<fillDTO> fills = dto.getFills();
        // 填写的判断题
        List<JudgeDTO> judges = dto.getJudges();

        Assert.isTrue((CollectionUtil.isNotEmpty(multis) || CollectionUtil.isNotEmpty(fills) || CollectionUtil.isNotEmpty(judges)), "请不要提交白卷");
        // 试卷id
        Integer examCode = dto.getExamCode();
        Assert.isTrue(ObjectUtil.isNotEmpty(examCode), "未获取到试卷id");
        ExamManage examManage = examManageMapper.selectById(examCode);
        Assert.isTrue(ObjectUtil.isNotEmpty(examManage), "未获取到试卷信息");
        // 获取试卷编号
        Integer paperId = examManage.getPaperId();
        List<PaperManage> paperManages = paperMapper.findById(paperId);
        Assert.isTrue(CollectionUtil.isNotEmpty(paperManages), "未获取到题目信息");
        Score score = BeanUtil.toBean(dto, Score.class);
        score.setEType(examManage.getType());
        // 插入考试记录
        baseMapper.insert(score);

        // 选择题
        List<Integer> multiIds = paperManages.stream().filter(p -> p.getQuestionType() == QuestionEnum.MULTI.getCode()).map(PaperManage::getQuestionId).collect(Collectors.toList());
        // 填空题
        List<Integer> fillIds = paperManages.stream().filter(p -> p.getQuestionType() == QuestionEnum.FILL.getCode()).map(PaperManage::getQuestionId).collect(Collectors.toList());
        // 判断题
        List<Integer> judgeIds = paperManages.stream().filter(p -> p.getQuestionType() == QuestionEnum.JUDGE.getCode()).map(PaperManage::getQuestionId).collect(Collectors.toList());

        // 考卷选择题
        List<MultiQuestion> multiQuestions = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(multiIds)) {
            multiQuestions = multiQuestionMapper.selectBatchIds(multiIds);
        }
        // 考卷填空题
        List<FillQuestion> fillQuestions = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(fillIds)) {
            fillQuestions = fillQuestionMapper.selectBatchIds(fillIds);
        }
        // 考卷判断题
        List<JudgeQuestion> judgeQuestions = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(judgeIds)) {
            judgeQuestions = judgeQuestionMapper.selectBatchIds(judgeIds);
        }
        Date now = new Date();
        // 数据转换(选择题)
        for (MultiQuestion multiQuestion : multiQuestions) {
            MultiQuestionHistory bean = BeanUtil.toBean(multiQuestion, MultiQuestionHistory.class);
            bean.setStudentId(studentId);
            bean.setScoreId(score.getScoreId());
            bean.setAnswerTime(now);
            if (CollectionUtil.isNotEmpty(multis)) {
                multis.stream().filter(m -> m.getId().equals(bean.getQuestionId())).findFirst().ifPresent(m -> {
                    bean.setFillIn(m.getRightAnswer());
                });
            }
            multiQuestionHistoryMapper.insert(bean);
        }

        // 数据转换（填空题）
        for (FillQuestion fillQuestion : fillQuestions) {
            FillQuestionHistory bean = BeanUtil.toBean(fillQuestion, FillQuestionHistory.class);
            bean.setStudentId(studentId);
            bean.setScoreId(score.getScoreId());
            bean.setAnswerTime(now);
            if (CollectionUtil.isNotEmpty(fills)) {
                fills.stream().filter(f -> f.getId().equals(bean.getQuestionId())).findFirst().ifPresent(f -> {
                    bean.setFillIn(f.getAnswer());
                });
            }
            fillQuestionHistoryMapper.insert(bean);
        }

        for (JudgeQuestion judgeQuestion : judgeQuestions) {
            JudgeQuestionHistory bean = BeanUtil.toBean(judgeQuestion, JudgeQuestionHistory.class);
            bean.setStudentId(studentId);
            bean.setScoreId(score.getScoreId());
            bean.setAnswerTime(now);
            if (CollectionUtil.isNotEmpty(judges)) {
                judges.stream().filter(j -> j.getId().equals(bean.getQuestionId())).findFirst().ifPresent(j -> {
                    bean.setFillIn(j.getAnswer());
                });
            }
            judgeQuestionHistoryMapper.insert(bean);
        }
        return 1;
    }

    @Override
    public List<Score> findAll() {
        LambdaQueryWrapper<Score> wrapper = Wrappers.lambdaQuery(Score.class).orderByDesc(Score::getScoreId);
        return baseMapper.selectList(wrapper);
    }

    @Override
    public IPage<Score> findByStudentId(Page page, Integer studentId) {
        // 分页
        LambdaQueryWrapper<Score> wrapper = Wrappers.lambdaQuery(Score.class).eq(Score::getStudentId, studentId).orderByDesc(Score::getScoreId);
        return baseMapper.selectPage(page, wrapper);
    }

    @Override
    public List<Score> findById(Integer studentId) {
        return baseMapper.selectList(Wrappers.lambdaQuery(Score.class).eq(Score::getStudentId, studentId));
    }

    @Override
    public List<Score> findByExamCode(Integer examCode) {
        return baseMapper.findByExamCode(examCode);
    }

    @Override
    public Map<String, Object> scoresHistory(Integer scoreId) {
        Map<String, Object> res = new HashMap<>();
        Score score = baseMapper.selectById(scoreId);
        Assert.isTrue(ObjectUtil.isNotEmpty(score), "未获取到考试记录");
        res.put("score", score);

        // 选择题记录
        List<MultiQuestionHistory> multis = multiQuestionHistoryMapper.selectByScoreId(scoreId);
        res.put("multis", multis);
        // 判断题记录
        List<JudgeQuestionHistory> judges = judgeQuestionHistoryMapper.selectByScoreId(scoreId);
        res.put("judges", judges);
        // 填空题记录
        List<FillQuestionHistory> fills = fillQuestionHistoryMapper.selectByScoreId(scoreId);
        res.put("fills", fills);

        return res;
    }
}
